<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="box1">防抖点击-非立即执行版</div>
    <div id="box2">防抖点击-立即执行版</div>
    <script>
        // 防抖和节流本质是不一样的。防抖是将多次执行变为一次执行；节流是将多次执行变成每个一段时间执行。

        //在学习防抖之前，我们先搞清楚，定时器和清楚定时器，我们知道通过我们用一个变量去存一个定时器，然后在适当的时机将这个定时器清除
        //我之前一直忽略了这个变量，我一直以为清除了这个定时器，这个变量会变成null，但是重新学习了下才知道，这个变量实际上保存的一直都是定时器
        //我们移除掉定时器，只是将定时器停止工作，但是却没有将这个变量的值变为null

        //为什么debounce要返回一个函数？
        //其实，我们在执行事件的时候，是执行防抖函数的返回值，多次执行的时候，并不是重复执行debounce这个函数，而是重复执行他内部返回的这个函数

        //下面我就来写一个防抖函数
        //其实原理就是采用一个定时器，多次执行的时候，防抖函数会清除掉之前的定时器
        function debounce1(fn,time){
            let timeout=null
            return function(){
                //完整一点，我们可以加上this指向，但是这里就不写了，可取看看https://www.jianshu.com/p/c8b86b09daf0
                if(timeout) clearTimeout(timeout);
                timeout=setTimeout(()=>{
                    fn()
                },time)
            }
        }
        let box1=document.getElementById('box1')
        function sayHi1(){
            console.log('防抖成功-非立即执行版')
        }
        box1.addEventListener('click',debounce1(sayHi1,1000))

        //接下来再<聊一聊防抖函数分为非立即执行版和立即执行版>
        //以上代码是非立即执行版
        //以下代码时立即执行版
        //其原理就是设置一个变量，通过这个变量的布尔值来控制fn函数是否可以执行，而控制这个变量的true还是false则通过保存定时器的那个变量，
        //而定时器那个变量只有在time到点之后才会变成null，
        function debounce2(fn,time){
            let timeout=null
            return function(){
                if(timeout) clearTimeout(timeout);
                let callNow=!timeout
                timeout=setTimeout(()=>{
                    timeout=null
                },time)
                if(callNow) fn()
            }
        }
        let box2=document.getElementById('box2')
        function sayHi2(){
            console.log('防抖成功-非立即执行版')
        }
        box2.addEventListener('click',debounce2(sayHi2,1000))
    </script>
</body>
</html>